package com.vay.de.dang.online.phone;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.location.Location;
import android.media.MediaDrm;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.provider.Settings;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.Formatter;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.vay.de.dang.online.util.VnUtil;
import com.vay.de.dang.online.util.VnContext;
import com.vay.de.dang.online.util.LocationHelper;
import com.vay.de.dang.online.web.BaseApi;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.UUID;

public class DeviceHelper {

    final static String IP_SPLIT_REGEX_KEY = "==";
    final static String[] KnownPipes = {"/dev/socket/qemud", "/dev/qemu_pipe"};
    final static long GB = 1024 * 1024 * 1024;

    public static String PhoneBrand = Build.MANUFACTURER;
    public static String PhoneModel = Build.MODEL;

    public static String getDeviceModel() {
        return PhoneBrand + "#" + PhoneModel;
    }

    public static PhoneInfo localDeviceInfo(Context context, String afAndroidId, String googleAdId) {

        PhoneInfo phoneInfo = new PhoneInfo();
        phoneInfo.setImei(getIMEI(context));
        phoneInfo.setImsi(getIMSI(context));
        phoneInfo.setModel(PhoneBrand + "#" + PhoneModel);
        phoneInfo.setDeviceModel(PhoneBrand + "#" + PhoneModel);
        phoneInfo.setDeviceMac(getDeviceMac(context));
        phoneInfo.setUuid(uuid());
        phoneInfo.setUuidOriginal(uuidOriginal());
        phoneInfo.setDeviceLanguage(VnContext.language);
        phoneInfo.setDeviceSoftwareVersion(getDeviceSoftwareVersion(context));
        phoneInfo.setNetworkOperator(getNetworkOperator(context));
        phoneInfo.setNetworkOperatorName(getNetworkOperatorName(context));
        phoneInfo.setCpuCores(getCpuCores());
        phoneInfo.setCpuInfo(getCpuInfo());
        String[] str = Build.SUPPORTED_ABIS;
        phoneInfo.setCpu(str[0] != null ? str[0] : "");

        // 没有定位时候
        Location location = LocationHelper.getInstance().getLocation();
        if (location == null) {
            LocationHelper.getInstance().requestLocation();
            long startTime = System.currentTimeMillis();
            while (true) {
                if (System.currentTimeMillis() - startTime > 5000)
                    break;
                location = LocationHelper.getInstance().getLocation();
                if (location != null) break;
                BaseApi.log("~~~等待定位成功");
                try {
                    Thread.sleep(20);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            location = LocationHelper.getInstance().getLocation();
        }

        if (location != null) {
            phoneInfo.setBlurLag(String.valueOf(location.getLatitude()));
            phoneInfo.setBlurLng(String.valueOf(location.getLongitude()));
            phoneInfo.setLocationCity(LocationHelper.getInstance().getCity());
            phoneInfo.setDetailAddress(LocationHelper.getInstance().getAddress());
            phoneInfo.setLocationAddress(LocationHelper.getInstance().getLocationAddress());
        } else {
            phoneInfo.setDetailAddress("");
            phoneInfo.setLocationCity("");
            phoneInfo.setLocationAddress("");
        }

        // 返回的有可能是null字符串
        if (TextUtils.isEmpty(afAndroidId) || afAndroidId == "null") {
            phoneInfo.setAndroidId(getAndroidId(context));
        } else {
            phoneInfo.setAndroidId(afAndroidId);
        }

        phoneInfo.setResolutionHeight(String.valueOf(getScreenHeights(context)));
        phoneInfo.setResolutionWidth(String.valueOf(getScreenWidths(context)));
        phoneInfo.setResolution(getScreenWidths(context) + "," + getScreenHeights(context));
        phoneInfo.setOs("Android");
        phoneInfo.setOsVersion(Build.VERSION.RELEASE);

        // 获取手机分辨率
        phoneInfo.setDisplayMetrics(getScreenWidths(context) + "," + getScreenHeights(context));

        phoneInfo.setAdbEnabled(getEnableAdb(context) ? 1 : 0);
        phoneInfo.setRuntimeAvailableMemory(getAvailableRuntime(context));
        phoneInfo.setRuntimeMaxMemory(getTotalRuntime(context));
        phoneInfo.setPhoneAvailableRam(getAvailMemory(context));
        phoneInfo.setAvailableRam(getAvailMemory(context));

        phoneInfo.setPhoneTotalRam(getTotalMemory(context));
        phoneInfo.setCpuSpeed(curCpuFreq());
        if (TextUtils.isEmpty(Build.FINGERPRINT)) {
            phoneInfo.setFingerPrint(Build.VERSION.CODENAME);
        } else {
            phoneInfo.setFingerPrint(Build.FINGERPRINT);
        }

        //电量
        phoneInfo.setBatteryPercent(getBattery(context));
        phoneInfo.setBluetoothEquipmentName(blueToothName());
        phoneInfo.setGaid(gAdId(googleAdId));
        phoneInfo.setNetworkType(NetWorkHelper.getNetworkState(context));
        phoneInfo.setTimeZone(currentTimeZone());
        phoneInfo.setSimulator(checkIsVirtualMachine(context) ? 1 : 0);
        phoneInfo.setSimState(hasSimCard(context) ? 1 : 0);
        phoneInfo.setRooted(isRooted() ? 1 : 0);

        phoneInfo.setSerialNumber(serialNumber());
        phoneInfo.setDeviceVersionType(Build.TYPE);
        phoneInfo.setTotalStorage(totalInternalMemorySize());
        phoneInfo.setAvailableStorage(availableInternalMemorySize());
        phoneInfo.setTimeZone(getCurrentTimeZone(context));

        phoneInfo.setNumberOfApplications(getInstallAppList(context));
        phoneInfo.setNumberOfMessages(getSmsNumber(context));
        phoneInfo.setNumberOfPhotos(getPhotoNumber(context));
        phoneInfo.setNumberOfSongs(getAudioNumber(context));
        phoneInfo.setNumberOfVideos(getVideoNumbers(context));

        // 1.wifi
        phoneInfo.setRouterMac(NetWorkHelper.getWifiMac(context));
        phoneInfo.setWifiName(NetWorkHelper.getWifiName(context));
        phoneInfo.setTurnOnTime(getTurnOnTime(context));

        phoneInfo.setRooted(getIsRooted(context) ? 1 : 0);
        phoneInfo.setHardware(Build.HARDWARE);
        phoneInfo.setProduct(Build.PRODUCT);
        phoneInfo.setRadioversion(Build.getRadioVersion());

        String[] ss = getSimInfo(context);
        phoneInfo.setPhonecardCount(ss[0]);
        phoneInfo.setOperatorName(ss[1]);
        String ip = getIPAddress(context);
        BaseApi.log("ip=" + ip);
        if (ip != null) {
            int pos = ip.indexOf("==");
            if (pos > 0) {
                try {
                    phoneInfo.setIp(ip.substring(pos + 2));
                } catch (Exception e) {
                    e.printStackTrace();
                    phoneInfo.setIp(ip);
                }
            } else {
                phoneInfo.setIp(ip);
            }
        } else {
            phoneInfo.setIp("0.0.0.0");
        }

        return phoneInfo;
    }

    public static String getIMEI(Context context) {
        String deviceId = "";
        try {
            if (isPhone(context)) {
                deviceId = getDeviceIdIMEI(context);
            } else {
                deviceId = getAndroidId(context);
            }
            if (deviceId == null) deviceId = "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return deviceId;
    }

    private static boolean isPhone(Context context) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return tm != null ? tm.getPhoneType() != TelephonyManager.PHONE_TYPE_NONE : false;
    }

    @SuppressLint("all")
    private static String getDeviceIdIMEI(Context context) {
        String imei = "";
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                return "";
            }
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                imei = tm.getImei();
            } else {
                imei = tm.getDeviceId();
            }
            if (imei == null) imei = "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return imei;
    }

    @SuppressLint("HardwareIds")
    public static String getAndroidId(Context context) {
        String rtn = "";
        try {
            rtn = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
            if (rtn == null) rtn = "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rtn;
    }

    public static String getIMSI(Context context) {
        String imsi = "";
        try {
            TelephonyManager telephonyManager =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (null != telephonyManager) {
                imsi = telephonyManager.getSubscriberId();
            }

            if (TextUtils.isEmpty(imsi)) {
                imsi = getSubscriberId(context, 0);
            }

            if (TextUtils.isEmpty(imsi)) {
                imsi = getSubscriberId(context, 1);
            }

        } catch (Exception e) {
            //e.printStackTrace();
        }
        return imsi;
    }

    private static String getSubscriberId(Context context, int subId) {
        try {
            TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Method getSubscriberId = manager.getClass().getMethod("getSubscriberId", Integer.class);
            Object value = getSubscriberId.invoke(manager, getSubId(context, subId));
            return value.toString();
        } catch (Exception e) {
            return "";
        }
    }

    private static int getSubId(Context context, int simId) {
        Uri uri = Uri.parse("content://telephony/siminfo");
        Cursor cursor = null;
        ContentResolver contentResolver = context.getContentResolver();
        try {
            cursor = contentResolver.query(uri, new String[]{"_id", "sim_id"},
                    "sim_id = ?", new String[]{String.valueOf(simId)}, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    return cursor.getInt(cursor.getColumnIndex("_id"));
                }
            }
        } catch (Exception e) {
        } finally {
            if (cursor != null) cursor.close();
        }
        return -1;
    }

    @SuppressLint("HardwareIds")
    public static String getDeviceMac(Context context) {
        String macAddress = "02:00:00:00:00:00";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<NetworkInterface> interfaces = null;
            try {
                interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
                for (NetworkInterface networkInterface : interfaces) {
                    if (networkInterface != null && !TextUtils.isEmpty(networkInterface.getName())) {
                        if ("wlan0".equalsIgnoreCase(networkInterface.getName())) {
                            byte[] macBytes = networkInterface.getHardwareAddress();
                            if (macBytes != null && macBytes.length > 0) {
                                StringBuilder str = new StringBuilder();
                                for (byte b : macBytes) {
                                    str.append(String.format("%02X:", b));
                                }
                                if (str.length() > 0) {
                                    str.deleteCharAt(str.length() - 1);
                                }
                                macAddress = str.toString();
                            }
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            if (context != null) {
                try {
                    WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
                    if (wifi != null) {
                        WifiInfo info = wifi.getConnectionInfo();
                        if (info != null) {
                            macAddress = info.getMacAddress();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return macAddress;
    }

    public static String uuid() {
        String uniqueId = "";
        try {
            UUID wideVineUuid = new UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L);
            MediaDrm wideVineMdD = null;
            try {
                wideVineMdD = new MediaDrm(wideVineUuid);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (null == wideVineMdD) {
                return "";
            }
            byte[] bytes = wideVineMdD.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID);
            StringBuilder sb = new StringBuilder();
            for (byte aByte : bytes) {
                sb.append(String.format("%02x", aByte));
            }

            uniqueId = sb.toString();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                wideVineMdD.close();
            } else {
                wideVineMdD.release();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return uniqueId;
    }

    private static String uuidOriginal() {
        String uniqueIdStr = "";
        try {
            UUID wideVineUuid = new UUID(-0x121074568629b532L, -0x5c37d8232ae2de13L);
            MediaDrm wideVineMdD = null;
            try {
                wideVineMdD = new MediaDrm(wideVineUuid);
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (null == wideVineMdD) {
                return "";
            }
            byte[] bytes = wideVineMdD.getPropertyByteArray(MediaDrm.PROPERTY_DEVICE_UNIQUE_ID);
            if (bytes != null) {
                uniqueIdStr = Arrays.toString(bytes);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                wideVineMdD.close();
            } else {
                wideVineMdD.release();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (uniqueIdStr == null) {
            uniqueIdStr = "";
        }
        return uniqueIdStr;
    }

    public static String getBattery(Context context) {
        try {
            BatteryManager batteryManager = ContextCompat.getSystemService(context, BatteryManager.class);
            if (batteryManager != null) {
                return String.valueOf(batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String blueToothName() {
        String blueToothName = "";
        try {
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            blueToothName = bluetoothAdapter.getName();
            if (blueToothName == null) return "";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return blueToothName;
    }

    public static int getScreenWidths(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    public static int getScreenHeights(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }

    public static boolean getEnableAdb(Context context) {
        return Settings.Secure.getInt(context.getContentResolver(), Settings.Global.ADB_ENABLED, 0) > 0;
    }

    public static String getTotalRuntime(Context context) {
        Runtime runtime = Runtime.getRuntime();
        return getUnit((double) runtime.maxMemory());
    }

    private static String getAvailableRuntime(Context context) {
        Runtime runtime = Runtime.getRuntime();
        long usedMemInMB = (runtime.totalMemory() - runtime.freeMemory());
        long maxHeapSizeInMB = runtime.maxMemory();
        return getUnit((double) (maxHeapSizeInMB - usedMemInMB));
    }

    private static String getUnit(double size) {
        return String.format(" %.4f%s", size / GB, "GB");
    }

    public static String getAvailMemory(Context context) {
        try {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
            if (null != am) {
                am.getMemoryInfo(mi);
                // mi.availMem; 当前系统的可用内存，将获取的内存大小规格化
                //return Formatter.formatFileSize(context, mi.availMem);
                return getUnit((double) mi.availMem);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getTotalMemory(Context context) {

        // 系统内存信息文件
        String cmd = "/proc/meminfo";
        String value;
        String[] arrayOfString;
        long initialMemory;
        FileReader localFileReader = null;
        BufferedReader localBufferedReader = null;
        try {
            localFileReader = new FileReader(cmd);
            localBufferedReader = new BufferedReader(localFileReader, 8192);
            // 读取mem info第一行，系统总内存大小
            value = localBufferedReader.readLine();
            arrayOfString = value.split("\\s+");

            if (arrayOfString.length == 1) {
                return arrayOfString[0];
            } else {
                // 获得系统总内存，单位是KB
                long i = Long.valueOf(arrayOfString[1]);
                //int值乘以1024转换为long类型
                initialMemory = i * 1024;
            }

            localBufferedReader.close();
        } catch (Exception ignore) {
            return "";
        } finally {
            closeIO(localFileReader);
            closeIO(localBufferedReader);
        }

        // Byte转换为KB或者MB，内存大小规格化
        // return Formatter.formatFileSize(context, initialMemory)

        return getUnit((double) initialMemory);
    }

    private static void closeIO(Closeable... closeables) {
        if (closeables == null) {
            return;
        }
        try {
            for (Closeable closeable : closeables) {
                closeable.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String curCpuFreq() {
        String result = "N/A";
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        try {
            fileReader = new FileReader("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
            bufferedReader = new BufferedReader(fileReader);
            String text = bufferedReader.readLine();
            // text.trim() ;
            // result = text.trim { it <= ' ' }
            //result = String.format("%sKHz", result)
            return text != null ? text + "KHz" : "";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeIO(fileReader, bufferedReader);
        }
        return result;
    }

    // 方式1：执行adb 命令获得//below android 8.0// 传音手机 Android 9 不能获取此属性
    // android O(安卓 8.0)
    // android O_MR1(安卓8.1)、安卓9
    // 版本>=android Q（安卓10）

    @SuppressLint("MissingPermission")
    private static String serialNumber() {
        String serial = "";
        try {
            // 版本>=android Q（安卓10）
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                try {
                    // 方式1：执行adb 命令获得
                    Runtime runtime = Runtime.getRuntime();
                    Process process = runtime.exec("getprop ro.serialno");
                    InputStream is = process.getInputStream();
                    InputStreamReader isr = new InputStreamReader(is);
                    BufferedReader br = new BufferedReader(isr);
                    serial = br.readLine();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return serial;
                // android O_MR1(安卓8.1)、安卓9
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
                if (Build.BRAND.toUpperCase() == "TECNO" || Build.BRAND.toUpperCase() == "ITEL" || Build.BRAND.toUpperCase() == "INFINIX") {
                    // 传音手机 Android 9 不能获取此属性
                } else {
                    serial = Build.getSerial();
                }
                // android O(安卓 8.0)
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                serial = Build.SERIAL;
                //below android 8.0
            } else {
                // 方式1：执行adb 命令获得
                Runtime runtime = Runtime.getRuntime();
                Process process = runtime.exec("getprop ro.serialno");
                InputStream is = process.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                serial = br.readLine();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return serial;
    }

    public static String currentTimeZone() {
        String strTz = "";
        try {
            TimeZone tz = TimeZone.getDefault();
            if (null != tz) {
                strTz = tz.getDisplayName(false, TimeZone.SHORT);
            }
            return strTz;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return strTz;
    }

    public static Boolean checkIsVirtualMachine(Context context) {
        return (notHasBlueTooth()
                || notHasLightSensorManager(context)
                || isFeatures()
                || checkIsNotRealPhone()
                || checkPipes());
    }

    public static Boolean notHasBlueTooth() {
        BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
        // 如果有蓝牙不一定是有效的。获取蓝牙名称，若为null 则默认为模拟器
        return ba == null || TextUtils.isEmpty(ba.getName());
    }

    public static Boolean notHasLightSensorManager(Context context) {
        try {
            SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
            if (null != sensorManager) {
                return sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) != null;
            }
        } catch (Exception ignore) {
            ignore.printStackTrace();
        }
        return false;
    }

    public static Boolean isFeatures() {
        return (Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.toLowerCase().contains("vbox")
                || Build.FINGERPRINT.toLowerCase().contains("test-keys")
                || Build.MODEL.contains("google_sdk")
                || Build.MODEL.contains("Emulator")
                || Build.MODEL.contains("Android SDK built for x86")
                || Build.MANUFACTURER.contains("Genymotion")
                || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
                || "google_sdk" == Build.PRODUCT);
    }

    public static Boolean checkIsNotRealPhone() {
        String cpuInfo = readCpuInfo();
        return cpuInfo.contains("intel") || cpuInfo.contains("amd");
    }

    public static String readCpuInfo() {
        String result = "";
        try {
            String[] args = new String[]{"/system/bin/cat", "/proc/cpuinfo"};
            ProcessBuilder cmd = new ProcessBuilder(args);
            Process process = cmd.start();
            StringBuilder stringBuilder = new StringBuilder();
            String readLine = "";
            BufferedReader responseReader =
                    new BufferedReader(new InputStreamReader(process.getInputStream(), Charset.forName("UTF-8")));
            while ((readLine = responseReader.readLine()) != null) {
                stringBuilder.append(readLine);
            }
            responseReader.close();
            result = stringBuilder.toString().toLowerCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static Boolean checkPipes() {
        for (String pipes : KnownPipes) {
            File qemuSocket = new File(pipes);
            if (qemuSocket.exists()) {
                return true;
            }
        }
        return false;
    }// nexus 5x "/su/bin/"

    public static Boolean isRooted() {

        // nexus 5x "/su/bin/"
        String[] paths = {
                "/system/xbin/",
                "/system/bin/",
                "/system/sbin/",
                "/sbin/",
                "/vendor/bin/",
                "/su/bin/"};
        try {
            for (int i = 0; i < paths.length; i++) {
                String path = paths[i] + "su";
                if (new File(path).exists()) {
                    String execResult = exec(new String[]{"ls", "-l", path});
                    return !TextUtils.isEmpty(execResult) && execResult.indexOf("root") != execResult.lastIndexOf(
                            "root"
                    );
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

    private static String exec(String... exec) {

        String ret = "";
        ProcessBuilder processBuilder = new ProcessBuilder(exec);
        BufferedReader bufferedReader = null;
        try {
            Process process = processBuilder.start();
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                ret += line;
            }
            process.getInputStream().close();
            process.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeIO(bufferedReader);
        }
        return ret;
    }

    public static Boolean hasSimCard(Context context) {
        TelephonyManager telMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        int simState = telMgr.getSimState();
        return !(simState == TelephonyManager.SIM_STATE_ABSENT || simState == TelephonyManager.SIM_STATE_ABSENT);
    }

    //获取内部存储根目录
    //系统的空间描述类
    //每个区块占字节数
    //区块总数
    public static String totalInternalMemorySize() {
        //获取内部存储根目录
        File path = Environment.getDataDirectory();
        //系统的空间描述类
        StatFs stat = new StatFs(path.getPath());
        //每个区块占字节数
        long blockSize = stat.getBlockSizeLong();
        //区块总数
        long totalBlocks = stat.getBlockCountLong();
        return getUnit((double) (totalBlocks * blockSize));

    } //获取可用区块数量

    public static String availableInternalMemorySize() {
        File path = Environment.getDataDirectory();
        StatFs stat = new StatFs(path.getPath());
        long blockSize = 0;
        //获取可用区块数量
        long availableBlocks = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            blockSize = stat.getBlockSizeLong();
            availableBlocks = stat.getAvailableBlocksLong();
        } else {
            blockSize = stat.getBlockSize();
            availableBlocks = stat.getAvailableBlocks();
        }

        return getUnit((double) (blockSize * availableBlocks));
    }

    private static String getDeviceSoftwareVersion(Context context) {
        try {
            TelephonyManager telephonyManager =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            return telephonyManager.getDeviceSoftwareVersion().toString();
        } catch (Exception e) {
            return "";
        }
    }

    private static String getNetworkOperator(Context context) {
        try {
            TelephonyManager manager =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            return manager.getNetworkOperator();
        } catch (Exception e) {
            return "";
        }
    }

    private static String getNetworkOperatorName(Context context) {
        try {
            TelephonyManager manager =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            return manager.getNetworkOperatorName();
        } catch (Exception e) {
            return "";
        }
    }

    private static String getCpuCores() {
        try {
            return Runtime.getRuntime().availableProcessors() + "";
        } catch (Exception e) {
            return "";
        }
    }

    private static String getCpuInfo() {
        String result = "";
        try {
            String cmd = "/proc/cpuinfo";
            FileReader fr = new FileReader(cmd);
            BufferedReader localBufferedReader = new BufferedReader(fr);
            do {
                result = localBufferedReader.readLine();
                if (result.contains("Hardware")) {
                    return result.split(":")[1];
                }
            } while (result != null);
            localBufferedReader.close();
        } catch (Exception e) {
        }
        return "";
    }

    private static String getSmsNumber(Context context) {
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(Uri.parse("content://sms"),
                    null, null, null, null);
            return cursor != null ? String.valueOf(cursor.getCount()) : "0";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return "0";
    }

    private static String getPhotoNumber(Context context) {
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,
                    MediaStore.Images.Media.DEFAULT_SORT_ORDER);
            return cursor != null ? String.valueOf(cursor.getCount()) : "0";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        return "0";
    }

    private static String getInstallAppList(Context context) {
        try {
            PackageManager packageManager = context.getPackageManager();
            List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
            return packageInfoList != null ? String.valueOf(packageInfoList.size()) : "0";
        } catch (Exception e) {

        }
        return "0";
    }

    private static String getTurnOnTime(Context context) {
        try {
            long longTime = System.currentTimeMillis() - SystemClock.elapsedRealtime();
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(longTime));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private static String getCurrentTimeZone(Context context) {
        try {
            TimeZone tz = TimeZone.getDefault();
            if (null != tz) {
                return tz.getDisplayName(false, TimeZone.SHORT);
            }
        } catch (Exception e) {

        }
        return "";
    }

    private static String getAudioNumber(Context context) {
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
                    MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
            return cursor != null ? String.valueOf(cursor.getCount()) : "0";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return "0";
    }

    private static String getVideoNumbers(Context context) {
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(
                    MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null,
                    MediaStore.Video.Media.DEFAULT_SORT_ORDER);
            return cursor != null ? String.valueOf(cursor.getCount()) : "0";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return "0";
    }

    private static Boolean getIsRooted(Context context) {
        // nexus 5x "/su/bin/"
        List<String> paths = Arrays.asList(
                "/system/bin/",
                "/system/xbin/",
                "/sbin/",
                "/system/sd/xbin/",
                "/system/bin/failsafe/",
                "/data/local/xbin/",
                "/data/local/bin/",
                "/data/local/",
                "/system/sbin/",
                "/usr/bin/",
                "/vendor/bin/",
                "/su/bin/"
        );
        try {
            for (String path : paths) {
                //val path = paths[i] + "su"
                if (!new File(path).exists()) continue;
                String execResult = exec("ls", "-l", path);
                return !TextUtils.isEmpty(execResult) && execResult.indexOf("root") != execResult.lastIndexOf("root");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private static String[] getSimInfo(Context context) {
        try {
            SubscriptionManager subscriptionManager = (SubscriptionManager) context.getSystemService(AppCompatActivity.TELEPHONY_SUBSCRIPTION_SERVICE);
            List<SubscriptionInfo> mSubInfoList = subscriptionManager.getActiveSubscriptionInfoList();

            StringBuilder s = new StringBuilder("");
            for (SubscriptionInfo it : mSubInfoList) {
                if (it.getCarrierName() != null) {
                    if (s.length() > 0) s.append(",");
                    s.append(it.getCarrierName());
                }
            }

            return new String[]{String.valueOf(mSubInfoList.size()), s.toString()};
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new String[]{"0", ""};
    }

    public static String getIPAddress(Context context) {

        // 方式1
        String ip = getIPAddress1(context);

        // 方式2
        if (TextUtils.isEmpty(ip)) {
            ip = getIPAddress2();
        }

        // 方式3
        if (TextUtils.isEmpty(ip)) {
            ip = getIPAddress3(context);
        }

        return ip;
    }

    @SuppressLint("PrivateApi")
    public static String getIPAddress1(Context context) {
        try {
            ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            final Class<ConnectivityManager> cmClass = ConnectivityManager.class;
            final Method methodGetActiveLinkProperties = cmClass.getDeclaredMethod("getActiveLinkProperties");
            final LinkProperties linkProperties = (LinkProperties) methodGetActiveLinkProperties.invoke(cm);
            if (linkProperties == null) {
                return null;
            }
            final Class<LinkProperties> linkPropertiesClass = LinkProperties.class;
            final Method methodGetAllAddresses = linkPropertiesClass.getDeclaredMethod("getAllAddresses");
            final List<InetAddress> inetAddresses = (List<InetAddress>) methodGetAllAddresses.invoke(linkProperties);
            if (inetAddresses != null) {
                final StringBuilder stringBuilder = new StringBuilder();
                for (InetAddress inetAddress : inetAddresses) {
                    if (inetAddress != null) {
                        if (!TextUtils.isEmpty(stringBuilder)) {
                            stringBuilder.append(IP_SPLIT_REGEX_KEY);
                        }
                        stringBuilder.append(inetAddress.getHostAddress());
                    }
                }
                return stringBuilder.toString();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getIPAddress2() {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface networkInterface : interfaces) {
                List<InetAddress> addresses = Collections.list(networkInterface.getInetAddresses());
                for (InetAddress address : addresses) {
                    if (address == null) continue;
                    if (address instanceof Inet4Address) {
                        return address.getHostAddress();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getIPAddress3(Context context) {
        WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        return Formatter.formatIpAddress(ipAddress);
    }

    private static String gAdId(String googleAdId) {
        if (!VnUtil.isEmpty(googleAdId)) {
            return googleAdId;
        } else {
            try {
                AdvertisingIdClient.Info info = AdvertisingIdClient.getAdvertisingIdInfo(VnContext.instance().getContext());
                return info.getId();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return "";
    }
}
